using System;
using System.Collections.Generic;
using System.Xml.Serialization;
using System.IO;
using System.Text;
using System.Collections;
using System.Resources;
using Microsoft.Win32;

namespace Level65.ClipShow
{
    public class Storage
    {
        private const string THUMBNAIL_DIR = "MediaThumbnails";
        private const string PLAYLIST_DIR = "MediaPlaylists";
        private const string MEDIALIB_DIR = "MediaSources";
        private const string APP_WORK_DIR = "clipShow Settings";
        private const string TAGS_DIR = "TagSettings";


        public Storage()
        {
            if (!Directory.Exists(GetApplicationSettingsDir()))
            {
                Directory.CreateDirectory(GetApplicationSettingsDir());
            }

            if (!Directory.Exists(GetLibraryDir()))
            {
                Directory.CreateDirectory(GetLibraryDir());
            }

            if (!Directory.Exists(GetThumbnailDir()))
            {
                Directory.CreateDirectory(GetThumbnailDir());

            }

            if (!Directory.Exists(GetPlaylistDir()))
            {
                Directory.CreateDirectory(GetPlaylistDir());
            }

            if (!Directory.Exists(GetTagSettingsDir()))
            {
                Directory.CreateDirectory(GetTagSettingsDir());
            }
        }

        public void PersistSettings(Settings source)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(Settings));

            string writeFilePath = String.Format("{0}\\Settings.xml",
                GetApplicationSettingsDir());
            TextWriter writer = new StreamWriter(writeFilePath);
            serializer.Serialize(writer, source);
            writer.Close();
        }

        public void RemoveThumbnailWork()
        {
            string writeFilePath = String.Format("{0}\\Thumbs.xml",
                GetThumbnailDir());
            try 
            {
                File.Delete(writeFilePath);
            }
            catch
            {
            }
        }
        public void PersistThumbnailWork(ThumbnailWork source)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(ThumbnailWork));

            string writeFilePath = String.Format("{0}\\Thumbs.xml",
                GetThumbnailDir());
            TextWriter writer = new StreamWriter(writeFilePath);
            serializer.Serialize(writer, source);
            writer.Close();
        }

        public ThumbnailWork GetThumbnailWork()
        {
            try
            {
                string settingsFilePath = string.Format("{0}\\Thumbs.xml", GetThumbnailDir());
                if (File.Exists(settingsFilePath))
                {
                    XmlSerializer serializer = new XmlSerializer(typeof(ThumbnailWork));
                    FileStream fs = new FileStream(settingsFilePath, FileMode.Open);
                    ThumbnailWork result = (ThumbnailWork)serializer.Deserialize(fs);
                    fs.Close();
                    return (result);
                }
                else
                {
                    return (new ThumbnailWork());
                }
            }
            catch
            {
                return (new ThumbnailWork());
            }
        }

        public Settings GetSettings()
        {
            try
            {
                string settingsFilePath = string.Format("{0}\\Settings.xml", GetApplicationSettingsDir());
                if (File.Exists(settingsFilePath))
                {
                    XmlSerializer serializer = new XmlSerializer(typeof(Settings));
                    FileStream fs = new FileStream(settingsFilePath, FileMode.Open);
                    Settings result = (Settings)serializer.Deserialize(fs);
                    fs.Close();
                    return (result);
                }
                else
                {
                    return (new Settings());
                }
            }
            catch
            {
                return (new Settings());
            }
        }

        public void PurgeCatalog()
        {
            try
            {
                foreach (string fileName in Directory.GetFiles(this.GetLibraryDir(), "*.xml"))
                {
                    DateTime now = System.DateTime.Now;
                    try
                    {
                        TimeSpan fileAge = now.Subtract(File.GetLastWriteTime(fileName));
                        // If file is over a day old, remove it
                        if (fileAge.Days > 1)
                        {
                            try
                            {
                                // Only purge files created in Startup Process
                                if (!GetMediaLibrary(fileName).WatchFolders)
                                {
                                    File.Delete(fileName);
                                }
                            }
                            catch
                            {
                                // Do nothing
                            }
                        }
                    }
                    catch (ArgumentOutOfRangeException)
                    {
                        // fileCreationTime is not valid, so re-throw the exception.
                        throw;
                    }
                }
            }
            catch
            {
                // Ignore for now
            }
        }
        public int GetMediaLibraryCount()
        {
            try
            {
                return (Directory.GetFiles(GetLibraryDir(), "*.xml").Length);
            }
            catch
            {
                return (0);
            }
        }
        public ArrayList GetMediaLibraries()
        {
            ArrayList results = new ArrayList();
            foreach (string fileName in Directory.GetFiles(GetLibraryDir(), "*.xml"))
            {
                try
                {
                    results.Add(GetMediaLibrary(fileName));
                }
                catch (SystemException se)
                {
                    if (se.Message.Equals("There is an error in XML document (0, 0)."))
                    {
                        try
                        {
                            // We found a corrupt playlist file 
                            File.Delete(fileName);
                        }
                        catch { }
                    }
                }
            }
            return (results);
        }

        public ArrayList GetMyCollections()
        {
            ArrayList results = new ArrayList();
            foreach (string fileName in Directory.GetFiles(GetPlaylistDir(), "*.xml"))
            {
                try
                {
                    results.Add(GetClipCollection(fileName));
                }
                catch (SystemException se)
                {
                    if (se.Message.Equals("There is an error in XML document (0, 0)."))
                    {
                        try
                        {
                            // We found a corrupt playlist file 
                            File.Delete(fileName);
                        }
                        catch { }
                    }
                }
            }
            return (results);
        }
        public ClipShowContent GetMediaLibrary(string sourceFilePath)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(ClipShowContent));
            FileStream fs = new FileStream(sourceFilePath, FileMode.Open);
            ClipShowContent result = (ClipShowContent)serializer.Deserialize(fs);
            fs.Close();
            return (result);
        }

        public ClipCollection GetClipCollection(string sourceFilePath)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(ClipCollection));
            FileStream fs = new FileStream(sourceFilePath, FileMode.Open);
            ClipCollection result = (ClipCollection)serializer.Deserialize(fs);
            result.MediaSourceFilePath = sourceFilePath;
            fs.Close();
            return (result);
        }

        public ClipShowContent GetSnagCollection()
        {

            string snagFilePath = String.Format("{0}\\snagItems.xml", GetApplicationSettingsDir());

            if (File.Exists(snagFilePath))
            {
                try
                {
                    XmlSerializer serializer = new XmlSerializer(typeof(ClipShowContent));
                    FileStream fs = new FileStream(snagFilePath, FileMode.Open);
                    ClipShowContent result = (ClipShowContent)serializer.Deserialize(fs);

                    fs.Close();
                    return (result);
                }
                catch
                {
                    ClipShowContent result = new ClipShowContent();
                    result.ContentSourceName = "my snags";
                    return (result);
                }
            }
            else
            {
                ClipShowContent result = new ClipShowContent();
                result.ContentSourceName = "my snags";
                return (result);
            }
        }

        public string[] GetTagFile(string fileName, string[] defaultResult)
        {
            try
            {
                string tagDir = GetTagSettingsDir();
                string sourceFilePath = String.Format("{0}\\{1}", tagDir, fileName);
                XmlSerializer serializer = new XmlSerializer(typeof(string[]));
                FileStream fs = new FileStream(sourceFilePath, FileMode.Open);
                string[] result = (string[])serializer.Deserialize(fs);
                fs.Close();
                return (result);
            }
            catch
            {
                return defaultResult;
            }
        }

        public ArrayList GetChannelSources()
        {
            ArrayList results = new ArrayList();
            string channelFilePath = String.Format("{0}\\Channels",
                GetApplicationSettingsDir());
            foreach (string fileName in Directory.GetFiles(channelFilePath, "*.xml"))
            {
                try
                {
                    ClipCollection mc = GetClipCollection(fileName);
                    results.Add(mc);
                }
                catch (SystemException se)
                {
                    if (se.Message.Equals("There is an error in XML document (0, 0)."))
                    {
                        try
                        {
                            // We found a corrupt playlist file 
                            File.Delete(fileName);
                        }
                        catch { }
                    }
                }
            }

            return (results);
        }

        public string PersistMediaLibrary(ClipShowContent cm)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(ClipShowContent));

            string writeFilePath = String.Format("{0}\\{1}.xml",
                GetLibraryDir(), cm.ContentSourceName);
            TextWriter writer = new StreamWriter(writeFilePath);
            serializer.Serialize(writer, cm);
            writer.Close();
            return (writeFilePath);
        }

        public void PersistTagFile(string[] source, string fileName)
        {
            string tagDir = GetTagSettingsDir();
            XmlSerializer serializer = new XmlSerializer(typeof(string[]));

            string writeFilePath = String.Format("{0}\\{1}", tagDir, fileName);
            if (!File.Exists(writeFilePath))
            {
                TextWriter writer = new StreamWriter(writeFilePath);
                serializer.Serialize(writer, source);
                writer.Close();
            }

        }
        public void PersistChannel(ClipCollection mc, bool createAsx)
        {
            string channelDir = GetPlaylistDir();
            XmlSerializer serializer = new XmlSerializer(typeof(ClipCollection));

            string writeFilePath = String.Format("{0}\\{1}.xml",
                channelDir, mc.Name);
            TextWriter writer = new StreamWriter(writeFilePath);
            serializer.Serialize(writer, mc);
            writer.Close();

            if (createAsx)
            {
                mc.CreateASX(GetAsxTargetDir());
            }
        }

        public void PersistSnagCollection(ClipShowContent mc)
        {
            string snagFilePath = String.Format("{0}\\snagItems.xml", GetApplicationSettingsDir());
            XmlSerializer serializer = new XmlSerializer(typeof(ClipShowContent));
            TextWriter writer = new StreamWriter(snagFilePath);
            serializer.Serialize(writer, mc);
            writer.Close();
        }

        public static string GetAsxTargetDir()
        {
            string myFolder = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures);
            string result = String.Format("{0}Users\\Public\\Videos\\clipShow playlists", Path.GetPathRoot(myFolder));

            if (!Directory.Exists(result))
            {
                Directory.CreateDirectory(result);
            }
            return (result);
        }
        public string GetPlaylistDir()
        {
            string filePath = String.Format("{0}\\{1}",
                GetApplicationSettingsDir(),
                PLAYLIST_DIR);
            return (filePath);

        }
        public string GetThumbnailDir()
        {
            string filePath = String.Format("{0}\\{1}",
                GetApplicationSettingsDir(),
                THUMBNAIL_DIR);
            return (filePath);
        }

        public string GetTagSettingsDir()
        {
            string filePath = String.Format("{0}\\{1}",
                GetApplicationSettingsDir(),
                TAGS_DIR);
            return (filePath);
        }

        private string GetLibraryDir()
        {
            string filePath = String.Format("{0}\\{1}",
                GetApplicationSettingsDir(),
                MEDIALIB_DIR);
            return (filePath);
        }
        private string GetApplicationSettingsDir()
        {
            string filePath = String.Format("{0}\\{1}",
                Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData),
                APP_WORK_DIR);
            return (filePath);
        }

        public string MediaLibraryPath(string contentLibName)
        {
            return (String.Format("{0}\\{1}.xml",
                GetApplicationSettingsDir(), contentLibName));
        }
    }
}
